package entidades;

import util.MySQL;
import java.util.List;
import java.util.HashMap;
import java.util.LinkedList;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.google.gson.Gson;
import util.TimerActualizarCapCiclo;
import util.TimerForTesting;

/**
 *
 * @author JFM
 */
public class Usuario extends Entidad
	{
	private String username;
	private String password;
	private String nombre;
	private String apellido;
	private boolean activo;
	
	private int perfilId;
	private Perfil perfil;

	static final String NOMBRE_TABLA = "usuarios";

	private List<String> permisos;

	// --- Constructores --- //

	public Usuario()
		{
		id = 0;
		username = "";
		password = "";
		nombre = "";
		apellido = "";
		activo = true;

		perfilId = 0;
		perfil = null;
		
		permisos = null;
		}

	public Usuario(int id) throws SQLException
		{ super(id); }

	public Usuario(String id) throws SQLException
		{ super(id); }

	public Usuario(ResultSet result) throws SQLException
		{ super(result); }

	public Usuario(ResultSet result, String prefix) throws SQLException
		{ super(result, prefix); }


	// --- Metodos get()/set() --- //

	public String getUsername()
		{ return username; }
	public void setUsername(String username)
		{ this.username = (username != null)? username : ""; }

	public String getPassword()
		{ return password; }
	public void setPassword(String password)
		{ this.password = password; }

	public String getNombre()
		{ return nombre; }
	public void setNombre(String nombre)
		{ this.nombre = nombre; }

	public String getApellido()
		{ return apellido; }
	public void setApellido(String apellido)
		{ this.apellido = (apellido != null)? apellido : ""; }

	public boolean isActivo()
		{ return activo; }
	public void setActivo(boolean activo)
		{ 
                  this.activo = activo;
          }
	public void setActivo(String activo)
		{ this.activo = activo != null && ( activo.compareTo("1") == 0 || activo.compareTo("true") == 0); }

	public int getPerfilId()
		{ return perfilId; }
	public void setPerfilId(int perfilId)
		{ this.perfilId = perfilId; }
	public void setPerfilId(String perfilId)
		{ try{this.perfilId = Integer.parseInt(perfilId);}catch(Exception e) {this.perfilId = 0;} }

	public Perfil getPerfil() throws SQLException
		{
		if(perfil == null || perfilId != perfil.getId())
			{ perfil = new Perfil(perfilId); }
		return perfil;
		}
	public void setPerfil(Perfil tipo)
		{ this.perfil = tipo; }

	@Override
	public String getDescriptor()
		{ return username; }
	
	@Override
	public String toJson()
		{
		HashMap map = new HashMap();
		map.put("id", id);
		map.put("username", username);
		map.put("password", password);
		map.put("nombre", nombre);
		map.put("apellido", apellido);
		map.put("perfilId", perfilId);
		map.put("activo", activo);
		return new Gson().toJson(map);
		}



	// --- Metodos MySQL --- //

	@Override
	public String getNombreTabla()
		{ return NOMBRE_TABLA; }

	@Override
	public void leer(ResultSet result, String prefijo) throws SQLException
		{
		this.setId(result.getInt(prefijo + "id"));
		this.setUsername(result.getString(prefijo + "username"));
		this.setPassword(result.getString(prefijo + "keyword"));
		this.setNombre(result.getString(prefijo + "nombre"));
		this.setApellido(result.getString(prefijo + "apellido"));
		this.setActivo(result.getBoolean(prefijo + "activo"));

		this.setPerfilId(result.getInt(prefijo + "perfil_id"));
		}

	@Override
	public void guardar() throws SQLException
		{
		ResultSet result = MySQL.executeQuery("Call Usuarios_Save(" +
				MySQL.formatId(id) + "," +
				MySQL.format(username) + "," +
				MySQL.format(password) + "," +
				MySQL.format(nombre) + "," +
				MySQL.format(apellido) + "," +
				MySQL.formatBit(activo) + "," +
				MySQL.formatId(perfilId) + ")");

		if(result.next())
			{
			if( result.getMetaData().getColumnCount() == 1)
				{
				String msj = result.getString("mensaje");
				throw new SQLException(msj);
				}
			else
				{ this.leer(result); }
			}

		result.getStatement().close();
		}

	@Override
	public void borrar() throws SQLException
		{ Usuario.borrar(id+""); }

	public static void borrar(String id) throws SQLException
		{ MySQL.executeUpdate("Call Usuarios_Delete("+id+")"); }

	public static List<Usuario> listar() throws SQLException
		{ return (List) Entidad.listar(Usuario.class, NOMBRE_TABLA, "username ASC"); }

	public void login() throws SQLException
		{
		ResultSet result = MySQL.executeQuery("SELECT * FROM " + NOMBRE_TABLA + " WHERE activo = 1 AND username = " + MySQL.format(username) + " AND keyword = " + MySQL.format(password));
		if(result.next()) {this.leer(result);}
		result.getStatement().close();
		}

	public static Usuario login(String username, String password) throws SQLException
		{
		Usuario usuario = null;
		ResultSet result = MySQL.executeQuery("SELECT * FROM " + NOMBRE_TABLA + " WHERE activo = 1 AND username = " + MySQL.format(username) + " AND keyword = " + MySQL.format(password));
		if(result.next()) { usuario = new Usuario(result); }
		result.getStatement().close();
                TimerActualizarCapCiclo.getInstance();
                TimerForTesting.getInstance();
		return usuario;
		}

	public boolean tienePermiso(String lugar, String accion)
		{
		if(permisos == null)
			{
			try{
		        permisos = new LinkedList();
				ResultSet result = MySQL.executeQuery("SELECT * FROM permisos_x_usuarios_view WHERE id = "+id);
				while(result.next())
					{ permisos.add(result.getString("lugar") + ";" + result.getString("accion")); }
				result.getStatement().close();
				}catch(Exception e) {}
			}
			
		return (permisos!=null)? permisos.contains(lugar + ";" + accion) : false;
		}
	}
